﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Collections;
using System.Timers;

namespace WindowsFormsApplication1.Snake
{
    /// <summary>
    /// 蛇
    /// </summary>
    public class Palette
    {
        int width=20;
        int height=20;
        Color color;
        Graphics g;
        ArrayList blocks;
        public Deriction direction;
        Timer timerBlock;
        Block food;
        int size=20;
        int level=1;
        bool IsGameOver=false;
        private int[] speed = new int[] { 500, 450, 400, 350, 300, 250, 200, 150, 100, 50 };// 游戏速度

        public void Start()
        {
            this.food = GetFood();
            timerBlock = new Timer(this.speed[this.level]);
            timerBlock.Elapsed += new ElapsedEventHandler(OnBlockTimeEvent);
            timerBlock.AutoReset=true;
            timerBlock.Start();
        }

        private void OnBlockTimeEvent(object Source, ElapsedEventArgs e)
        {
            this.Move();
            if (this.CheckDead())
            {
                this.timerBlock.Stop();
                this.timerBlock.Dispose();
                System.Windows.Forms.MessageBox.Show("Score:"+this.blocks.Count+",Game Over!");
            }
        }

        public Palette(int width, int height, int size, Color color, Graphics g, int level)
        {
            this.width = width;
            this.height = height;
            this.size = size;
            this.color = color;
            this.g = g;
            this.level = level;
            this.blocks = new ArrayList();
            this.blocks.Insert(0,new Block(this.size,Color.Red,new Point(width/2,height/2)));
            this.direction = Deriction.Right;
        }

        private Block GetFood()
        {
           Block b=null;
           Random r = new Random();
           bool redo = false;
           while (true)
           {
               redo = false;
               int x = r.Next(this.width);
               int y = r.Next(this.height);
               for (int i = 0; i < this.blocks.Count; i++)
               {
                 Block bc = (Block)(this.blocks[i]);
                 if (x == bc._point.X && y == bc._point.Y)
                 {//检测坐标是否重叠
                     redo = true;
                 }
               }

               if (redo == false)
               {
                   b = new Block(this.size, Color.Black, new Point(x, y));
                   break;
               }
           }
           return b;               
        }

        /// <summary>
        /// 检测
        /// </summary>
        /// <returns></returns>
        public bool CheckDead()
        {
            //生成新坐标
            Block head= (Block)(this.blocks[0]);//蛇头
            int x = head._point.X;
            int y = head._point.Y;
            if (x < 0 || y < 0 || x>=this.width || y>=this.height)
            {//边界检测
                this.IsGameOver = true;
                return true;
            }

            for (int i = 1; i < this.blocks.Count; i++)
            {
                Block bc = (Block)(this.blocks[i]);
                if (x == bc._point.X && y == bc._point.Y)
                {//检测坐标是否重叠
                    this.IsGameOver = true;
                    return true;
                }
            }
            this.IsGameOver = false;
            return  false;
        }

        //更新画布
        public void PaintPalette(Graphics g)
        {
            g.Clear(this.color);
            this.food.Paint(g);
            foreach(Block b in this.blocks)
            {
                b.Paint(g);
            }
        }

        public void Move()
        {
            Block head = (Block)blocks[0];
            Point p = new Point(head._point.X, head._point.Y - 1);
            switch (this.direction)
            {
                case Deriction.Up:
                    p = new Point(head._point.X, head._point.Y - 1);
                    break;
                case Deriction.Down:
                    p = new Point(head._point.X, head._point.Y +1);
                    break;
                case Deriction.Left:
                    p = new Point(head._point.X-1, head._point.Y);
                    break;
                case Deriction.Right:
                    p = new Point(head._point.X+1, head._point.Y);
                    break;
            }
            //新蛇头
            Block NewHead = new Block(this.size, Color.Red, p);
            //判断是否和食物冲突
            if (this.food._point == p)
            {
                this.food = GetFood();
            }
            else
            {
                this.blocks.RemoveAt(this.blocks.Count - 1);
            }
            this.blocks.Insert(0, NewHead);
            this.PaintPalette(this.g);
        }
    }
}
